package modules.loan.controller;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import luxing.common.controller.BaseController;
import luxing.exception.BusinessException;
import luxing.hibernate.CriteriaQuery;
import luxing.util.AverageCapitalPlusInterestUtil;
import luxing.util.AverageCapitalUtil;
import luxing.util.CriteriaQueryUtil;
import luxing.util.DateUtil;
import luxing.util.ValidatorUtil;
import luxing.web.model.DataGrid;
import luxing.web.model.Result;
import modules.loan.entity.LoanContract;
import modules.loan.entity.Loan;
import modules.loan.service.LoanContractService;
import modules.sys.entity.Log;
import modules.sys.service.LogService;

/**
 * 
 * @author zzc
 *
 */
@Controller
@RequestMapping("/loanContractController")
public class LoanContractController extends BaseController {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(LoanContractController.class);

	@Autowired
	private LogService logService;
	@Autowired
	private LoanContractService loanContractService;

	/**
	 * 列表页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "index")
	public ModelAndView index(HttpServletRequest request) {
		return new ModelAndView("modules/loan/loanContract-list");
	}

	/**
	 * 列表数据
	 * 
	 * @param loanContract
	 * @param request
	 * @param response
	 * @param dataGrid
	 */
	@RequestMapping(params = "list")
	public void list(LoanContract loanContract, HttpServletRequest request, HttpServletResponse response,
			DataGrid dataGrid) {
		try {
			CriteriaQuery cq = new CriteriaQuery(LoanContract.class, dataGrid);
			CriteriaQueryUtil.assembling(cq, loanContract, request.getParameterMap());
			cq.add();
			loanContractService.listByPage(cq, true);
			dataGrid.setFooter(
					"principal,interest,totalAmount,realPrincipal,realInterest,realTotalAmount,oweAmount,sn:合计");
			listView(response, dataGrid);
		} catch (Exception e) {
			logger.error("贷款合同查询失败", e);
			throw new BusinessException("贷款合同查询失败", e);
		}
	}

	/**
	 * 增加页面
	 * 
	 * @return
	 */
	@RequestMapping(params = "goAdd")
	public ModelAndView goAdd(HttpServletRequest req) {
		return new ModelAndView("modules/loan/loanContract-add");
	}

	/**
	 * 查看页面
	 * 
	 * @param insurance
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "goDetail")
	public ModelAndView goDetail(LoanContract loanContract, HttpServletRequest request) {
		if (StringUtils.isNotBlank(loanContract.getId())) {
			loanContract = loanContractService.get(LoanContract.class, loanContract.getId());
			request.setAttribute("loanContractPage", loanContract);
		}
		return new ModelAndView("modules/loan/loanContract-detail");
	}

	/**
	 * 还款计划表
	 * 
	 * @return
	 */
	@RequestMapping(params = "planTab")
	public ModelAndView planTab(HttpServletRequest req) {
		List<Loan> loanList = new ArrayList<Loan>();
		BigDecimal totalPrincipal = new BigDecimal(0);
		BigDecimal totalInterest = new BigDecimal(0);
		if (StringUtils.isNotBlank(req.getParameter("period")) && StringUtils.isNotBlank(req.getParameter("startDate"))
				&& StringUtils.isNotBlank(req.getParameter("genType"))) {
			// 期数
			int period = Integer.valueOf(req.getParameter("period")).intValue();
			// 起息日
			Date startDate = DateUtil.strToDate(req.getParameter("startDate"), "yyyy-MM-dd");
			// 生成方式
			String genType = req.getParameter("genType");
			/** 自动生成 */
			if (StringUtils.equals(genType, "1")) {
				// 贷款金额
				BigDecimal contractPrincipal = new BigDecimal(req.getParameter("principal"));
				// 利率
				BigDecimal rate = new BigDecimal(req.getParameter("rate")).multiply(new BigDecimal(0.01));
				// 还款方式
				String repaymentType = req.getParameter("repaymentType");
				if (StringUtils.equals(repaymentType, LoanContract.REPAYMENTTYPE_EIAI)) {
					// 等本等息
					BigDecimal principal = contractPrincipal.divide(new BigDecimal(period), 1, BigDecimal.ROUND_DOWN);
					BigDecimal interest = contractPrincipal.multiply(rate).setScale(1, BigDecimal.ROUND_DOWN);
					Calendar cal = DateUtil.getCalendar(startDate);
					for (int i = 1; i <= period; i++) {
						Loan loan = new Loan();
						loan.setPeriod(i);
						loan.setEndDate(cal.getTime());
						loan.setPrincipal(principal);
						loan.setInterest(interest);
						loan.setTotalAmount(loan.getPrincipal().add(loan.getInterest()));
						cal.add(Calendar.MONTH, 1);
						totalPrincipal = totalPrincipal.add(loan.getPrincipal());
						totalInterest = totalInterest.add(loan.getInterest());
						loanList.add(loan);
					}
				}
				if (StringUtils.equals(repaymentType, LoanContract.REPAYMENTTYPE_ACPI)) {
					// 等额本息
					Calendar cal = DateUtil.getCalendar(startDate);
					Map<Integer, BigDecimal> principalMap = AverageCapitalPlusInterestUtil
							.getPerMonthPrincipal(contractPrincipal, rate, period);
					Map<Integer, BigDecimal> interestMap = AverageCapitalPlusInterestUtil
							.getPerMonthInterest(contractPrincipal, rate, period);
					for (int i = 1; i <= period; i++) {
						Loan loan = new Loan();
						loan.setPeriod(i);
						loan.setEndDate(cal.getTime());
						loan.setPrincipal(principalMap.get(i));
						loan.setInterest(interestMap.get(i));
						loan.setTotalAmount(loan.getPrincipal().add(loan.getInterest()));
						cal.add(Calendar.MONTH, 1);
						totalPrincipal = totalPrincipal.add(loan.getPrincipal());
						totalInterest = totalInterest.add(loan.getInterest());
						loanList.add(loan);
					}
				}
				if (StringUtils.equals(repaymentType, LoanContract.REPAYMENTTYPE_AC)) {
					// 等额本金
					Calendar cal = DateUtil.getCalendar(startDate);
					Map<Integer, BigDecimal> interestMap = AverageCapitalUtil.getPerMonthInterest(contractPrincipal,
							rate, period);
					for (int i = 1; i <= period; i++) {
						Loan loan = new Loan();
						loan.setPeriod(i);
						loan.setEndDate(cal.getTime());
						loan.setPrincipal(AverageCapitalUtil.getPerMonthPrincipal(contractPrincipal, period));
						loan.setInterest(interestMap.get(i));
						loan.setTotalAmount(loan.getPrincipal().add(loan.getInterest()));
						cal.add(Calendar.MONTH, 1);
						totalPrincipal = totalPrincipal.add(loan.getPrincipal());
						totalInterest = totalInterest.add(loan.getInterest());
						loanList.add(loan);
					}
				}

			} else if (StringUtils.equals(genType, "2")) {
				/** 手动生成 */
				Calendar cal = DateUtil.getCalendar(startDate);
				for (int i = 1; i <= period; i++) {
					Loan loan = new Loan();
					loan.setPeriod(i);
					loan.setEndDate(cal.getTime());
					cal.add(Calendar.MONTH, 1);
					loanList.add(loan);
				}
			}
		}
		req.setAttribute("totalPrincipal", totalPrincipal);
		req.setAttribute("totalInterest", totalInterest);
		req.setAttribute("totalAmount", totalPrincipal.add(totalInterest));
		req.setAttribute("loanList", loanList);
		return new ModelAndView("modules/loan/loanContract-tab");
	}

	/**
	 * 投保险种
	 * 
	 * @return
	 */
	@RequestMapping(params = "planTabDetail")
	public ModelAndView planTabDetail(HttpServletRequest req) {
		if (StringUtils.isNotBlank(req.getParameter("id"))) {
			LoanContract loanContract = loanContractService.get(LoanContract.class, req.getParameter("id"));
			List<Loan> loanList = loanContract.getLoanList();
			req.setAttribute("loanList", loanList);
			req.setAttribute("loanContractPage", loanContract);
		}
		return new ModelAndView("modules/loan/loanContractDetail-tab");
	}

	/**
	 * 增加
	 * 
	 * @param loanContract
	 * @param request
	 * @return
	 */
	@RequestMapping(params = "doAdd")
	@ResponseBody
	public Result doAdd(LoanContract loanContract, HttpServletRequest request) {
		String msg = null;
		try {
			if (CollectionUtils.isNotEmpty(loanContract.getLoanList())) {
				// bean校验
				msg = ValidatorUtil.validate(loanContract);
				if (StringUtils.isNotBlank(msg)) {
					return Result.error(msg);
				}
				loanContractService.save(loanContract);
				msg = "责任人\"" + loanContract.getOwner().getName() + "\"借款增加成功";
				logger.info(msg);
				logService.addLogInfo(msg, Log.OPERATE_ADD);
			}
		} catch (Exception e) {
			msg = "责任人\"" + loanContract.getOwner().getName() + "\"借款增加失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}

	/**
	 * 删除
	 * 
	 * @return
	 */
	@RequestMapping(params = "doDel")
	@ResponseBody
	public Result doDel(LoanContract loanContract, HttpServletRequest request) {
		String msg = null;
		try {
			loanContract = loanContractService.get(LoanContract.class, loanContract.getId());
			if (loanContract.getStatus().equals(LoanContract.STATUS_ING)) {
				return Result.error("还款中，无法删除");
			}
			if (loanContract.getStatus().equals(LoanContract.STATUS_YES)) {
				return Result.error("已还款，无法删除");
			}
			loanContractService.delete(loanContract);
			msg = "借款\"" + loanContract.getSn() + "\"删除成功";
			logger.info(msg);
			logService.addLogInfo(msg, Log.OPERATE_DEL);
		} catch (Exception e) {
			msg = "借款\"" + loanContract.getSn() + "\"删除失败";
			logger.error(msg, e);
			throw new BusinessException(msg, e);
		}
		return Result.success(msg);
	}
}
